Part Number Hot Search : 
UPA1428 SMF11A KT835 RM4004 SHT20P U12C05 LC899 BA6407AF
Product Description
Full Text Search
 

To Download AN81 Datasheet File

  If you can't view the Datasheet, Please click here to try to view without PDF Reader .  
 
 


  Datasheet File OCR Text:
  application note 1 of 16 www.xicor.com june, 2000 AN81 interfacing 2-wire serial memories to hitachi h8/3000 microcontrollers by applications staff this code demonstrates how the x24165/645 family of serial eeproms could be interfaced to the hitachi h8/ 3000 microcontroller family when connected as shown in figure 1. the interface requires two of the port pins available on h8 family devices to implement the inter- face. this interface was tested with the x24645, however by addressing smaller arrays this code can be easily adapted for lower density memories. vcc vcc u2 h8/3042 (fp) d0 18 d8 27 d9 28 d10 29 d11 30 d12 31 d13 32 d14 33 d15 34 a0 36 a1 37 a2 38 a3 39 a4 40 a5 41 a6 42 a7 43 pb0 2 a8 45 a9 46 a10 47 a11 48 a12 49 a13 50 d1 19 d2 20 d3 21 pb1 3 d4 23 d5 24 d6 25 d7 26 a14 51 a15 52 a16 53 a17 54 a18 55 a19 56 pb2 4 pb3 5 pb4 6 pb5 7 pb6 8 pb7 9 p7.0 78 p7.1 79 p7.2 80 p7.3 81 p7.4 82 p7.5 83 p7.6 84 p7.7 85 pa0 93 pa1 94 pa2 95 pa3 96 pa4 97 pa5 98 pa6 99 pa7 100 p8.0 87 p8.1 88 p8.2 89 p8.3 90 p8.4 91 xtal 67 extal 66 p9.0 12 p9.1 13 p9.2 14 p9.3 15 p9.4 16 p9.5 17 reso 10 p6.0 58 p6.1 59 p6.2 60 p6.3 69 p6.4 70 p6.5 71 p6.6 72 md0 73 md1 74 md2 75 avcc 76 avss 86 vref 77 nmi 64 res 63 stby 62 clkout 61 u1 x24645 s1 s2 3 wp 7 sda 5 scl 6 10k 10k 10k 16mhz 22pf 22pf 2 10k 10k figure 1. typical hardware connection for interfacing a x24645 to the h8/3042 microcontroller
2 of 16 AN81 application note www.xicor.com june, 2000 .h8300h .file "h8x24645.asm" ; test code for interfacing xicor x24645 serial eeproms to the hitachi h8/3042 ; outputs all read bytes, in ascii hex form, serially ; revision: 1.13 02/21/96 ; expects the h8/3042 hard-wired in mode 1: 8-bit bus-width, expanded address ; space (0x00000-0xfffff), internal rom disabled, internal ram enabled ; (0xff710-0xfff0f), 16.0000 mhx xtal .include "h8stddef.inc" ; h8/3042 standard register definitions ; h8/3042 specific equates .equ h8ramtop, 0xfff0f ; highest onboard ram address (2048 bytes) .equ h8rambot, 0xff710 ; lowest onboard ram address .equ intmask, 0b11000000 ; ccr interrupt mask (i and ui bits) ; xicor eeprom device-specific equates .equ sda, bit_1 ; port bit for serial data (h8 in/out) .equ scl, bit_2 ; port bit for serial clock (h8 out) .equ s1, bit_3 ; port bit for chip select 1 (h8 out) .equ s2, bit_4 ; port bit for chip select 2 (h8 out) .equ wp, bit_5 ; port bit for write protect (h8 out) .equ wpr, 0x1fff ; write protect register address .equ wel, bit_1 ; write enable latch (must be set to write ; eeprom, resets to zero) .equ rwel, bit_2 ; register write enable latch (must be set ; to change bp/wpen bits, resets to zero) .equ bp1, bit_4 ; block protect msb .equ bp0, bit_3 ; lsb .equ wpen, bit_7 ; write protect enable .equ xicor, pbdr ; h8/3042 data port assignment (pb) .equ xicorddr, pbddr ; h8/3042 data direction port assignment .equ xicorrd, 0b11111101 ; data direction register setup h8<-x24645 .equ xicorwr, 0b11111111 ; data direction register setup h8->x24645 .equ pagesize, 32 ; bytes per page .equ numbytes, 8192 ; number of bytes in eeprom .equ numpages, numbytes/pagesize ; number of pages in eeprom .equ pagemask, pagesize-1 ; mask out non-page bits .equ pagebndry, ~ pagemask ; mask out page bits (not pagemask) .equ addrmask, numbytes-1 ; mask out non-address bits .equ maxpolls, 50 ; maximum number of 'ack' poll attempts .equ rdflag, 0b00000001 ; read flag .equ wrflag, 0b00000000 ; write flag ; main equates .equ stacktop, h8ramtop-4 ; stack initializes here and builds down
3 of 16 AN81 application note www.xicor.com june, 2000 .equ allones, 0b11111111 ; all bits set .equ bigwrite, 170 ; test number of bytes to write (>5 pages) .equ rambfr0, h8rambot ; start of read/write buffer in on-board ram .equ rambfr1, h8rambot+pagesize ; second read/write buffer .equ rambfr2, rambfr1+bigwrite ; third read/write buffer .equ rambfr3, rambfr2+bigwrite ; fourth read/write buffer .equ databyte0, 0xf0 ; test byte 0 .equ databyte1, 0x0f ; 1 .equ databyte2, 0x55 ; 2 .equ databyte3, 0xaa ; 3 .equ xaddrb, 0x1555 ; test byte write/read address (loc 5461) .equ testpage, 165 ; test page number (0->numpages-1) .equ xaddrbp, numbytes-10 ; test block protect read/write address .equ xaddrbw, 14*pagesize+5 ; eeprom bigwrite destination .equ h8ramloc0, h8rambot+1047 ; power up ram test location 0 .equ h8ramloc1, h8rambot+1597 ; 1 .equ pwrupflgs, 256*databyte3+databyte2 ; 0xaa55 .equ devaddr, 0b00000001 ; device address (s1=1, s2=0) ; start of code ; .org 0x000100 ; h8vectbl.asm (h8/3042 interrupt vector jump table at address 0x00000) .long 0x00000100 ; 0 reset .long _bogus_int ; 1 reserved .long _bogus_int ; 2 reserved .long _bogus_int ; 3 reserved .long _bogus_int ; 4 reserved .long _bogus_int ; 5 reserved .long _bogus_int ; 6 reserved .long _bogus_int ; 7 external interrupt (nmi) .long _bogus_int ; 8 trap instruction (4 sources) .long _bogus_int ; 9 trap instruction (4 sources) .long _bogus_int ; 10 trap instruction (4 sources) .long _bogus_int ; 11 trap instruction (4 sources) .long _bogus_int ; 12 external interrupt irq0 .long _bogus_int ; 13 external interrupt irq1 .long _bogus_int ; 14 external interrupt irq2 .long _bogus_int ; 15 external interrupt irq3 .long _bogus_int ; 16 external interrupt irq4 .long _bogus_int ; 17 external interrupt irq5 .long _bogus_int ; 18 reserved .long _bogus_int ; 19 reserved .long _bogus_int ; 20 wovi watchdog timer .long _bogus_int ; 21 cmi refresh controller .long _bogus_int ; 22 reserved .long _bogus_int ; 23 reserved .long _bogus_int ; 24 imia0 gra0 compare match/input capture .long _bogus_int ; 25 imib0 grb0 compare match/input capture .long _bogus_int ; 26 ovi0 overflow 0 .long _bogus_int ; 27 reserved .long _bogus_int ; 28 imia1 gra1 compare match/input capture .long _bogus_int ; 29 imib1 grb1 compare match/input capture
4 of 16 AN81 application note www.xicor.com june, 2000 .long _bogus_int ; 30 ovi1 overflow 1 .long _bogus_int ; 31 reserved .long _bogus_int ; 32 imia2 gra2 compare match/input capture .long _bogus_int ; 33 imib2 grb2 compare match/input capture .long _bogus_int ; 34 ovi2 overflow 2 .long _bogus_int ; 35 reserved .long _bogus_int ; 36 imia3 gra3 compare match/input capture .long _bogus_int ; 37 imib3 grb3 compare match/input capture .long _bogus_int ; 38 ovi3 overflow 3 .long _bogus_int ; 39 reserved .long _bogus_int ; 40 imia4 gra4 compare match/input capture .long _bogus_int ; 41 imib4 grb4 compare match/input capture .long _bogus_int ; 42 ovi4 overflow 4 .long _bogus_int ; 43 reserved .long _bogus_int ; 44 dend0a dmac group 0 .long _bogus_int ; 45 dend0b dmac group 0 .long _bogus_int ; 46 dend1a dmac group 0 .long _bogus_int ; 47 dend1b dmac group 0 .long _bogus_int ; 48 reserved .long _bogus_int ; 49 reserved .long _bogus_int ; 50 reserved .long _bogus_int ; 51 reserved .long _bogus_int ; 52 eri0 receive error sci chan 0 .long _bogus_int ; 53 rxi0 receive data full sci chan 0 .long _bogus_int ; 54 txi0 transmit data empty sci chan 0 .long _bogus_int ; 55 tei0 transmit end sci chan 0 .long _bogus_int ; 56 eri1 receive error sci chan 1 .long _bogus_int ; 57 rxi1 receive data full sci chan 1 .long _bogus_int ; 58 txi1 transmit data empty sci chan 1 .long _bogus_int ; 59 tei1 transmit end sci chan 1 .long _bogus_int ; 60 adi a/d end _bogus_int: orc #0b11000000,ccr ; disable interrupts (i and ui) rte ; .org 0x000100 _powerup: ; initialization orc #intmask,ccr ; disable interrupts (i and ui) mov.l #stacktop,er7 ; initialize the stack pointer mov.b #0b00000000,r0l ; set access state control register to mov.b r0l,@astcr ; 2-state access for all areas bsr _init_xiport:16 ; initialize the eeprom i/o port mov.l #h8ramloc0,er1 ; point to power-up flag location 0 mov.b @er1,r0l ; ... and fetch the flag mov.l #h8ramloc1,er2 ; ... the other flag, location 1 mov.b @er2,r0h ; ... fetch it mov.w #pwrupflgs,r3 ; setup flag compare (and re-write) mov.b r3l,@er1 ; store first flag mov.b r3h,@er2 ; ... and the second (we've powered-up) cmp.w r0,r3 ; has reset brought us here? beq _test_recycle ; yes, complement all data this cycle xor.b r6h,r6h ; no, don't complement data this cycle bra _test_start
5 of 16 AN81 application note www.xicor.com june, 2000 _test_recycle: not.b r6h ; to complement or not to complement, ... ; enable writing to the eeprom _test_start: bclr #wp,@xicor ; write protect line low to enable eeprom mov.b #devaddr,r2l ; setup device address select (s1, s2) bsr _write_enable:16 ; enable eeprom writes (sets write enable latch) ; check device status mov.b #devaddr,r2l ; setup device address select (s1, s2) bsr _read_status:16 ; fetch status from write protect register ; write a single byte, then another mov.b #databyte3,r0l ; setup write test byte xor.b r6h,r0l ; complement if alternate test cycles mov.w #xaddrb,r1 ; setup target test address mov.b #devaddr,r2l ; setup device address select (s1, s2) bsr _byte_write:16 ; write byte mov.b #databyte2,r0l ; setup to write another test byte xor.b r6h,r0l ; complement if alternate test cycles mov.w #xaddrb+1,r1 ; setup target test address (next location) mov.b #devaddr,r2l ; setup device address select (s1, s2) bsr _byte_write:16 ; write byte ; read a single random byte mov.w #xaddrb,r1 ; setup the same address just written mov.b #devaddr,r2l ; setup device address select (s1, s2) bsr _byte_read_random:16 ; read byte at this address ; read a single byte at current address mov.w #xaddrb,r1 ; setup the same address just written mov.b #devaddr,r2l ; setup device address select (s1, s2) bsr _byte_read_current:16 ; read next byte ; generate a page of data in buffer by block moving page write data table ; to ram. this provides for complementing the data without placing the code ; inside the page write subroutine. mov.l #rambfr0,er3 ; setup destination address mov.l #_dataset0,er2 ; setup source address mov.b #pagesize,r1l ; setup byte count to transfer _xferloop: mov.b @er2+,r0l ; get the byte and bump the source pointer xor.b r6h,r0l ; complement if necessary mov.b r0l,@er3 ; stuff it into ram inc.l #1,er3 ; bump the destination pointer to next dec.b r1l ; click off another byte bne _xferloop ; continue until count=0
6 of 16 AN81 application note www.xicor.com june, 2000 ; write a single page (from buffer 0) mov.w #testpage,r1 ; setup eeprom target page mov.b #devaddr,r2l ; setup device address select (s1, s2) mov.l #rambfr0,er3 ; point to source data bsr _page_write:16 ; ... and write the page ; read a single page (into buffer 1) mov.w #testpage,r1 ; again, setup eeprom source page mov.b #devaddr,r2l ; setup device address select (s1, s2) mov.l #rambfr1,er3 ; point to destination buffer in onboard ram bsr _page_read:16 ; ... and read the page (into different bfr) ; setup a data buffer for a write sequence spanning many pages xor.w r1,r1 ; initialize byte sequence/count mov.l #rambfr1,er2 ; ... and point to the destination _bigwr_setup: mov.b r1l,r0l ; fetch byte to store xor.b r6h,r0l ; complement if required mov.b r0l,@er2 ; store a byte in the ram buffer inc.l #1,er2 ; bump pointer to next ram location inc.w #1,r1 ; count bytes stored/generate next byte cmp.w #bigwrite,r1 ; have we done 'em all? blt _bigwr_setup ; no, continue ; write a large number of contiguous bytes mov.w #bigwrite,r4 ; setup byte count mov.w #xaddrbw,r1 ; setup eeprom starting address mov.b #devaddr,r2l ; setup device address mov.l #rambfr1,er3 ; setup source data pointer bsr _write_seq:16 ; ... and write 'em ; read back the large number of bytes just written into another buffer mov.w #bigwrite,r4 ; setup to read 'em back ... here's count mov.w #xaddrbw,r1 ; eeprom source address mov.b #devaddr,r2l ; setup device address mov.l #rambfr2,er3 ; pointer to ram destination bsr _read_seq:16 ; block protect bset #wp,@xicor ; write protect line high to enable protect mov.b #0b10001000,r0l ; setup wpen, block protect upper 25% mov.b #devaddr,r2l ; setup device address bsr _write_protect:16 ; verify write protection state mov.b #devaddr,r2l ; setup device address select (s1, s2) bsr _read_status:16 ; fetch status from write protect register
7 of 16 AN81 application note www.xicor.com june, 2000 ; end of test terminal loop bclr #wp,@xicor ; write protect line low to enable writes mov.b #0b00000000,r0l ; setup to unprotect all blocks mov.b #devaddr,r2l ; setup device address bsr _write_protect:16 bset #wp,@xicor ; write protect line high to enable protect mov.b #devaddr,r2l ; setup device address select (s1, s2) bsr _read_status:16 ; fetch status from write protect register _endloop: bra _endloop ; eeprom interface subroutines for xicor x24645 ; name: _init_xiport ; function: initializes the h8 i/o port bit directions ; calls: none ; expects: nothing ; returns: nothing ; registers: perturbs r0l ; remarks must be called once initially to setup the i/o port _init_xiport: mov.b #xicorwr,r0l ; setup port data directions mov.b r0l,@xicorddr ; ... and load 'em bset #s1,@xicor ; chip select 1 high bset #s2,@xicor ; 2 bset #scl,@xicor ; clock high bset #wp,@xicor ; write protect line high, disable writes bset #sda,@xicor ; data line high rts ; initializes scl high and sda high ; name: _write_enable ; function: sets wel in wpr to enable eeprom writes ; calls: _byte_write ; expects: device select in r2l ; returns: carry clear if okay, set otherwise ; registers: alters r0l, r1, r2l ; remarks must be called after reset (power up), before writing eeprom _write_enable: mov.w #wpr,r1 ; setup write protect register address mov.b #0b00000010,r0l ; setup to write the wel bit bsr _byte_write:16 ; ... and do so rts ; name: _read_status ; function: reads the content of the write protect register (wpr) ; calls: _byte_read_random ; expects: device select in r2l ; returns: carry reset if okay, set otherwise ; registers: alters r0l, r1, r2l ; remarks
8 of 16 AN81 application note www.xicor.com june, 2000 _read_status: mov.w #wpr,r1 ; setup write protect register address bsr _byte_read_random:16 ; read the status of wpr rts ; name: _write_protect ; function: enables or disables software write protect (if wp high) ; calls: _byte_write ; expects: device select in r2l, write protect state in r0l: ; bit 7 wpen set to enable write protect, reset to disable ; bits 4:3 bp1:0 block protect identifier: ; none 00 ; top quarter 01 0x1800-0x1fff ; top half 10 0x1000-0x1fff ; all 11 0x0000-0x1fff ; returns: carry reset if okay, set otherwise ; registers: alters er0, r1, e2, r2h ; remarks on entry, r0l should contain the wpen and bp bits in their correct ; locations ... they are not verified. ; note that the final write to wpr requires 10 ms, however the normal ; timeout for eeprom write cycles is 5 ms. to compensate we repeat ; the polling for another 5 ms before we decide that the write was ; unsuccessful (carry set to one). _write_protect: mov.w r2,e2 ; preserve the device select mov.w r0,e0 ; ... and the protect code bsr _write_enable:16 bcs _write_prnack ; if acknowledge failed mov.b #0b00000110,r0l ; setup second byte in the sequence w/rwel mov.w #wpr,r1 ; ... and the wpr address mov.w e2,r2 ; recover device select bsr _byte_write:16 ; ... and write it! bcs _write_prnack ; if acknowledge failed mov.w e0,r0 ; recover protect code or.b #0b00000110,r0l ; ensure that wel and rwel are set mov.w #wpr,r1 ; again, the write protect register address mov.w e2,r2 ; recover device select bsr _byte_write:16 ; write it (5ms polling)! ; enter the following extended polling after ; the stop condition from _byte_write mov.w #wpr,r1 ; again, the write protect register address mov.b #maxpolls,r0h ; setup maximum poll attempts again (5ms) bsr _delay:16 _long_poll: mov.w e2,r2 ; ... and device select mov.b #wrflag,r2h ; setup write command bsr _send_slave_addr:16 bcc _longpoll_okay ; eeprom acknowledge (low) is write done bsr _stop:16 ; send stop sequence bsr _delay:16 dec.b r0h ; click off the poll count ... reached zero? bne _long_poll ; no, continue polling
9 of 16 AN81 application note www.xicor.com june, 2000 orc #0b00000001,ccr ; yes, timed out ... set carry (nack) rts ; scl high sda high _longpoll_okay: ; successful, carry=0 bsr _stop:16 _write_prnack: rts ; exits with scl high and sda high ; name: _byte_write ; function: writes a single byte to the xicor eeprom memory array ; calls: _send_byte, _send_slave_addr, _send_byte_addr, _write_poll, _stop ; expects: byte to be sent in r0l, address in r1, device select in r2l ; returns: acknowledge in the carry bit ; registers: r0, r1, r2, e1, e2 ; remarks: _byte_write: mov.b r0l,r0h ; preserve the byte to be written mov.w r1,e1 ; ... and its address mov.w r2,e2 ; ... and the select mov.b #wrflag,r2h ; setup read/write flag (bit 0=0, write) bsr _send_slave_addr:16 bcs _byte_wrnack ; eeprom did not acknowledge bsr _send_byte_addr:16 bcs _byte_wrnack ; failed acknowledge mov.b r0h,r0l ; recover byte to write to eeprom bsr _send_byte:16 ; and transmit it bcs _byte_wrnack ; negative acknowledge bsr _write_poll:16 ; poll for write completion rts ; exits with scl high and sda high _byte_wrnack: bsr _stop:16 ; output the stop sequence rts ; exits with scl high and sda high ; name: _byte_read_random ; function: reads a single byte from the xicor eeprom memory array ; calls: _send_byte, _recv_byte _send_word ; expects: serial eeprom byte address in r1, device select in r2l ; returns: byte read in r0l, carry set if any problem, reset means okay ; registers: alters e1, e2, r2h, r5l ; remarks: _byte_read_random: mov.w r1,e1 ; preserve the eeprom address mov.w r2,e2 ; ... and the select bits mov.b #wrflag,r2h ; setup read/write flag (bit 0=0, write) bsr _send_slave_addr:16 ; dummy write bcs _byte_rdnack ; if the acknowledge failed bsr _send_byte_addr:16 bcs _byte_rdnack ; eeprom failed acknowledge mov.w e1,r1 ; recover eeprom address mov.w e2,r2 ; ... and select code mov.b #rdflag,r2h ; setup read/write flag (bit 0=1, read) bsr _send_slave_addr:16 ; the actual read ... bcs _byte_rdnack ; acknowledge fail
10 of 16 AN81 application note www.xicor.com june, 2000 mov.b #0b10000000,r5l ; setup negative acknowledge bsr _recv_byte:16 ; read byte andc #0b11111110,ccr ; clear the carry _byte_rdnack: bsr _stop:16 ; output stop sequence rts ; exits with scl high and sda high ; name: _byte_read_current ; function: reads 'the next' byte from the xicor eeprom memory array ; calls: _send_slave_addr, _recv_byte, _stop ; expects: serial eeprom byte address in r1, device select in r2l ; returns: byte read in r0l, carry=0 if byte was read, =1 if not ; registers: r2h, r5l ; remarks: _byte_read_current: mov.b #rdflag,r2h ; setup read/write flag (bit 0=1, read) bsr _send_slave_addr:16 ; byte address not necessary bcs _byte_rdcnack ; acknowledge failed mov.b #0b10000000,r5l ; setup nack, only reading one byte bsr _recv_byte:16 ; read byte andc #0b11111110,ccr ; indicate we read the byte successfully _byte_rdcnack: bsr _stop:16 ; output the stop sequence rts ; exits with scl high and sda high ; name: _page_write ; function: sends a full page to the xicor eeprom ; calls: _send_byte, _write_poll, _send_slave_addr, _send_byte_addr, _stop ; expects: serial eeprom destination page number in r1, pointer to byte ; source in er3, device select in r2l ; returns: carry set if unsuccessful, cleared otherwise ; registers: alters r0l, er1, r2h, er3, r4 ; remarks: _page_write: mov.w #pagesize,r4 ; setup the number of bytes per page mulxu.w r4,er1 ; calculate eeprom byte address mov.w r1,e1 ; preserve the address mov.w r2,e2 ; ... and the select mov.b #wrflag,r2h ; setup read/write flag (bit 0=0, write) bsr _send_slave_addr:16 bcs _page_wrnack ; acknowledge fail bsr _send_byte_addr:16 bcs _page_wrnack ; acknowledge fail _page_wrloop: mov.b @er3+,r0l ; fetch next byte, point to next one bsr _send_byte:16 ; output it bcs _page_wrnack ; if acknowledge fails dec.b r4l ; click off another byte, done? bne _page_wrloop ; no, keep on bsr _stop:16 ; yes, output the stop sequence bsr _write_poll:16 ; wait until writing is complete ... _page_wrnack:
11 of 16 AN81 application note www.xicor.com june, 2000 bsr _stop:16 ; output the stop sequence rts ; exits with scl high and sda high ; name: _page_read ; function: reads a full page from the xicor eeprom ; calls: _send_byte, _poll_write _send_word ; expects: eeprom page number in r1, pointer to destination bytes in er3, ; select code in r2l ; returns: bytes read into destination and carry=0 if successful, carry ; set otherwise ; registers: alters r0l, er1, e2, r2h, er3, r4, r5l ; remarks: _page_read: mov.w #pagesize,r4 ; setup the number of bytes per page mulxu.w r4,er1 ; calculate eeprom byte address mov.w r1,e1 ; preserve the address mov.w r2,e2 ; ... and the select mov.b #wrflag,r2h ; setup read/write flag (bit 0=0, write) bsr _send_slave_addr:16 ; dummy write to setup address in eeprom bcs _page_rdnack ; if acknowledge fails ... bsr _send_byte_addr:16 bcs _page_rdnack mov.w e1,r1 ; recover eeprom address mov.w e2,r2 ; ... and device select mov.b #rdflag,r2h ; setup read/write flag (bit 0=1, read) bsr _send_slave_addr:16 ; the actual read ... bcs _page_rdnack ; acknowledge fail dec.b r4l ; so that the last byte read is count=0 _page_rdloop: mov.b #0b00000000,r5l ; setup acknowledge bsr _recv_byte:16 ; read byte mov.b r0l,@er3 ; store it inc.l #1,er3 ; point to next storage location dec.b r4l ; another one read, last one next? bne _page_rdloop ; no, continue reading mov.b #0b10000000,r5l ; yes, setup negative acknowledge bsr _recv_byte:16 ; read byte mov.b r0l,@er3 ; store it andc #0b11111110,ccr ; indicate success _page_rdnack: bsr _stop:16 ; we're done ... stop rts ; exits with scl high and sda high ; name: _read_seq ; function: reads a sequence of bytes from the xicor eeprom ; calls: _send_byte, _recv_byte _send_slave_addr, _send_byte_addr ; expects: eeprom source starting address in r1, count of bytes to read in r4, ; pointer to start of destination storage in er3, select in r2l ; returns: byte array in memory and carry reset if okay, carry set if not ; registers: alters r0l, e1, e2, r2h, er3, r4, r5l ; remarks: byte count (r4) is not limit verified (i.e. up to 65536 bytes may ; be read, cycling through the eeprom addresses) _read_seq: mov.w r1,e1 ; preserve the destination address
12 of 16 AN81 application note www.xicor.com june, 2000 mov.w r2,e2 ; ... and the select mov.b #wrflag,r2h ; setup read/write flag (bit 0=0, write) bsr _send_slave_addr:16 ; dummy write bcs _read_sqnack ; acknowledge fail bsr _send_byte_addr:16 bcs _read_sqnack ; failed acknowledge mov.w e1,r1 ; recover destination address mov.w e2,r2 ; ... and device select code mov.b #rdflag,r2h ; setup read/write flag (bit 0=1, read) bsr _send_slave_addr:16 ; the actual read ... bcs _read_sqnack ; acknowledge fail dec.w #1,r4 ; so that last byte read is count=0 _read_sqloop: mov.b #0b00000000,r5l ; setup acknowledge bsr _recv_byte:16 ; read byte mov.b r0l,@er3 ; ... and store it inc.l #1,er3 ; point to the next location dec.w #1,r4 ; ... and count it down, is this one last? bne _read_sqloop ; no, continue reading mov.b #0b10000000,r5l ; yes, setup negative acknowledge bsr _recv_byte:16 ; read byte mov.b r0l,@er3 ; ... and store it andc #0b11111110,ccr ; indicate success ... carry=0 _read_sqnack: bsr _stop:16 ; stop! rts ; exits with scl high and sda high ; name: _write_seq ; function: writes a sequence of bytes to the xicor eeprom ; calls: _send_byte, _send_slave_addr, _write_poll, _send_byte_addr ; expects: eeprom destination starting address in r1, count of bytes to write ; in r4, pointer to start of source storage in er3, select in r2l ; returns: carry set if successful, cleared otherwise ; registers: alters r0l, er1, e2, r2h, er3, er4 ; remarks: takes advantage of page write mode to minimize write times _write_seq: mov.w r1,e1 ; preserve the destination address mov.w r2,e2 ; ... and the select _wr_nextpg: mov.b #wrflag,r2h ; setup read/write flag (bit 0=0, write) bsr _send_slave_addr:16 ; start of the write sequence bcs _write_sqdone ; acknowledge fail bsr _send_byte_addr:16 ; next part of the address bcs _write_sqdone ; acknowledge fail _wr_sqloop: mov.b @er3+,r0l ; fetch byte to write and point to next one bsr _send_byte:16 ; send it bcs _write_sqdone ; acknowledge fail inc.w #1,e1 ; advance eeprom address dec.w #1,r4 ; click off another byte written mov.w e1,e4 ; get the current eeprom address and.w #pagemask,e4 ; mask out non-page bits ... page end? beq _page_end ; yes, do the polling thing ... or.w r4,r4 ; no, has the count reached zero?
13 of 16 AN81 application note www.xicor.com june, 2000 bne _wr_sqloop ; no, more bytes to write _page_end: ; yes, poll for write completion ... bsr _write_poll:16 bcs _write_sqdone ; polling timed out without an acknowledge or.w r4,r4 ; are there more bytes to write? beq _write_sqdone ; no, we're done ... mov.w e1,r1 ; yes, recover eeprom address ... mov.w e2,r2 ; ... and the device select bra _wr_nextpg ; continue writing the next page _write_sqdone: bsr _stop:16 ; done, send the stop sequence rts ; exits with scl high and sda high name: _send_slave_addr ; function: writes the first byte 'slave' address sequence to the xicor eeprom ; calls: _send_byte, -delay ; expects: eeprom destination starting address in r1, device select address ; in r2l, read/write flag in r2h (bit 0=0 for write, 1 for read) ; returns: acknowledge in carry (1=fail, 0=okay) ; registers: r0l, r0h, r1, r2, r3l ; remarks: _send_slave_addr: mov.b #xicorwr,r0l ; setup sda for output (h8->x24645) mov.b r0l,@xicorddr ; ... and load it bset #sda,@xicor ; guarantee that data (sda) is high bsr _delay:16 ; guarantee required time bset #scl,@xicor ; guarantee that clock (scl) is high and.b #0b00000011,r2l ; eliminate that which is not device address rotr.b r2l ; slip device address to upper two bits rotr.b r2l and.b #0b00011111,r1h ; mask away non-upper byte address bits shll.b r1h ; nudge byte address, make room for r/w bit mov.b r2h,r0l ; 0x00000000=write, 0x00000001=read and.b #0b00000001,r0l ; mask out any drivel from caller or.b r2l,r0l ; stuff device address ... or.b r1h,r0l ; ... and byte upper address, r/w bit bclr #sda,@xicor ; drop sda while scl high (start condition) bsr _send_byte ; go send the byte ... rts ; exits with scl low and sda low ; name: _send_byte_addr ; function: writes the second 'byte' address to the xicor eeprom ; calls: _send_byte ; expects: eeprom destination starting address in r1 ; returns: acknowledge in carry (1=fail, 0=okay) ; registers: r0l ; remarks: if required, must be called immediately after '_send_slave_addr' _send_byte_addr: mov.b r1l,r0l ; fetch destination address ls byte bsr _send_byte ; and send it ... rts ; exits with scl low and sda low ; name: _send_byte
14 of 16 AN81 application note www.xicor.com june, 2000 ; function: sends a byte to the xicor eeprom, serially shifting msb first ; calls: _delay ; expects: byte to be sent in r0l ; returns: acknowledge bit in carry (1=fail, 0=okay) ; registers: r0l, r0h, r2h ; remarks: _send_byte: mov.b #8,r2h ; setup bit count _send_loop: bsr _delay:16 ; delay set for 16mhz, 2-state (no waits) bclr #scl,@xicor ; clock (scl) low shll.b r0l ; slip ms bit into carry bst #sda,@xicor ; store carry state to port pin sda bsr _delay:16 bset #scl,@xicor ; clock (scl) high dec.b r2h ; count another bit, are we done? bne _send_loop ; no, continue ... bsr _delay:16 bclr #scl,@xicor ; yes, clock (scl) low mov.b #xicorrd,r0l ; setup sda for input (h8<-x24645) mov.b r0l,@xicorddr ; sda input bsr _delay:16 bset #scl,@xicor ; clock (scl) high bsr _delay:16 bld #sda,@xicor ; copy input pin (sda) into carry ... ack bclr #scl,@xicor ; clock (scl) low mov.b #xicorwr,r0l ; setup sda for output (h8->x24645) bclr #sda,@xicor ; sda low mov.b r0l,@xicorddr ; sda output rts ; exits with scl low and sda low ; name: _recv_byte ; function: receives a byte from the xicor eeprom, serially shifting msb first ; calls: _delay ; expects: acknowledge in r5l bit 7 (1=acknowledge, 0=negative acknowledge) ; returns: received byte in r0l ; registers: alters r0l, r0h, r2h, r5l ; remarks: clock rate limited for h8/3042 16mhz xtal and 2-state access _recv_byte: mov.b #8,r2h ; setup bit count mov.b #xicorrd,r0l ; setup sda for input (h8<-x24645) mov.b r0l,@xicorddr ; sda input _recv_loop: bsr _delay:16 bclr #scl,@xicor ; clock (scl) low bsr _delay:16 bld #sda,@xicor ; load sda port pin into carry rotxl.b r0l ; carry into lsb, msb into carry bset #scl,@xicor ; clock (scl) high dec.b r2h ; count another bit, are we done? bne _recv_loop ; no, continue ... bsr _delay:16 bclr #scl,@xicor ; yes, clock (scl) low
15 of 16 AN81 application note www.xicor.com june, 2000 mov.b #xicorwr,r0h ; setup sda for output (h8->x24645) mov.b r0h,@xicorddr ; sda output shll.b r5l ; move acknowledge bit into carry bst #sda,@xicor ; carry into sda ... h8 acknowledge bsr _delay:16 bset #scl,@xicor ; clock (scl) high bsr _delay:16 bclr #scl,@xicor ; clock (scl) low bclr #sda,@xicor ; remove h8 acknowledge (sda low) rts ; exits with scl low and sda low ; name: _write_poll ; function: monitors eeprom internal write completion status ; calls: _stop, _delay, _send_slave_addr ; expects: eeprom address in e1, select in e2 ; returns: carry set if polling times out, cleared if normal completion ; registers: alters r1, r2, r0h ; remarks: _write_poll: bsr _stop:16 ; polling starts from a stop condition mov.b #maxpolls,r0h ; setup maximum number of poll attempts bsr _delay:16 _poll_loop: mov.w e1,r1 ; recover eeprom address mov.w e2,r2 ; ... and device select mov.b #wrflag,r2h ; setup write command bsr _send_slave_addr:16 bcc _write_okay ; eeprom acknowledge (low) is write done bsr _stop:16 ; send stop sequence bsr _delay:16 dec.b r0h ; click off the poll count ... reached zero? bne _poll_loop ; no, continue polling orc #0b00000001,ccr ; yes, timed out ... set carry rts ; scl high sda high _write_okay: bsr _stop:16 rts ; scl high sda high ; name: _stop ; function: generates the eeprom stop sequence ; calls: _delay ; expects: nothing ; returns: nothing ; registers: none ; remarks: _stop: bclr #sda,@xicor ; stop condition requires sda low bsr _delay:16 ; wait ... bset #scl,@xicor ; clock (scl) high push.l er6 ; non-destructive 16-state delay (1.0 usec) pop.l er6 bsr _delay:16 ; wait ... bset #sda,@xicor ; raise sda while scl high (stop condition)
16 of 16 AN81 application note www.xicor.com june, 2000 rts ; exits with scl high and sda high ; name: _delay ; function: delays execution so that a 16mhz 2-state h8/3042 won't exceed ; eeprom operational timing ; calls: nothing ; expects: nothing ; returns: in a little while (actually 28 states or 1.75 usec at 16mhz) ; registers: none ; remarks: this delay should be reduced to optimize performance at ; other clock rates/access state settings _delay: ; 8 states (0.5 usec @ 16mhz) nop ; 2 states (0.125 usec) nop ; 2 states (0.125 usec) nop ; 2 states (0.125 usec) nop ; 2 states (0.125 usec) nop ; 2 states (0.125 usec) nop ; 2 states (0.125 usec) rts ; 8 states (0.5 usec) ; data tables _dataset0: .byte 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55 .byte 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 .byte 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55 .byte 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f


▲Up To Search▲   

 
Price & Availability of AN81

All Rights Reserved © IC-ON-LINE 2003 - 2022  

[Add Bookmark] [Contact Us] [Link exchange] [Privacy policy]
Mirror Sites :  [www.datasheet.hk]   [www.maxim4u.com]  [www.ic-on-line.cn] [www.ic-on-line.com] [www.ic-on-line.net] [www.alldatasheet.com.cn] [www.gdcy.com]  [www.gdcy.net]


 . . . . .
  We use cookies to deliver the best possible web experience and assist with our advertising efforts. By continuing to use this site, you consent to the use of cookies. For more information on cookies, please take a look at our Privacy Policy. X